<template>
  <div class="problemCreate">
    <div class="p-header">
      <div class="p-h-title" v-if="route.name !== 'problemedit'">
        <i class="iconfont icon-tianjia2"></i>创建题目
      </div>
      <div class="p-h-title" v-else>
        <i class="iconfont icon-bianji2"></i>编辑题目
      </div>
    </div>
    <n-form class="form" :model="problem" :rules="rules" ref="formRef">
      <n-form-item label="题目类型" path="problemType" class="f-item">
        <n-select
          placeholder="题目类型"
          v-model:value="problem.problemType"
          class="f-i-input"
          :options="problemTypeOptions"
          @change="
            (v) => {
              if (v == 1) {
                languages = [
                  {
                    language: 'Java',
                  },
                ];
                selectedLang = ['Java'];
              } else {
                languages = [
                  {
                    language: 'Java',
                  },
                  {
                    language: 'C',
                  },
                  {
                    language: 'C++',
                  },
                  {
                    language: 'C With O2',
                  },
                  {
                    language: 'C++ With O2',
                  },
                  {
                    language: 'Python2',
                  },
                  {
                    language: 'Python3',
                  },
                  {
                    language: 'PyPy2',
                  },
                  {
                    language: 'PyPy3',
                  },
                ];
                selectedLang = [
                  'Java',
                  'C',
                  'C++',
                  'C With O2',
                  'C++ With O2',
                  'Python2',
                  'Python3',
                  'PyPy2',
                  'PyPy3',
                ];
              }
            }
          "
        ></n-select>
      </n-form-item>
      <n-form-item label="题目展示ID" path="problemId" class="f-item">
        <n-input
          placeholder="题目展示ID"
          v-model:value="problem.problemId"
          class="f-i-input"
        ></n-input>
      </n-form-item>
      <n-form-item label="题目标题" path="title" class="f-item">
        <n-input
          placeholder="题目标题"
          v-model:value="problem.title"
          class="f-i-input"
        ></n-input>
      </n-form-item>
      <n-form-item label="题目描述" path="description" class="f-item">
        <v-md-editor
          class="mdEdit"
          :left-toolbar="toolbar"
          v-model="problem.description"
          :disabled-menus="[]"
          @upload-image="updateImage"
          height="300px"
          :before-preview-change="beforeChange"
        >
        </v-md-editor>
      </n-form-item>
      <n-form-item label="输入描述" path="inputDes" class="f-item">
        <v-md-editor
          class="mdEdit"
          :left-toolbar="toolbar"
          v-model="problem.inputDes"
          :disabled-menus="[]"
          @upload-image="updateImage"
          height="300px"
          :before-preview-change="beforeChange"
        ></v-md-editor>
      </n-form-item>
      <n-form-item label="输出描述" path="outputDes" class="f-item">
        <v-md-editor
          class="mdEdit"
          :left-toolbar="toolbar"
          v-model="problem.outputDes"
          height="300px"
          :disabled-menus="[]"
          @upload-image="updateImage"
          :before-preview-change="beforeChange"
        ></v-md-editor>
      </n-form-item>
      <div class="limit">
        <n-form-item class="l-item" label="时间限制(ms)" path="timeLimit">
          <n-input-number
            class="l-i-input"
            type="number"
            placeholder="时间限制"
            v-model:value="problem.timeLimit"
          >
          </n-input-number>
        </n-form-item>
        <n-form-item class="l-item" label="空间限制(mb)" path="memoryLimit">
          <n-input-number
            class="l-i-input"
            type="number"
            placeholder="空间限制"
            v-model:value="problem.memoryLimit"
          ></n-input-number>
        </n-form-item>
        <n-form-item class="l-item" label="栈限制(mb)" path="stackLimit">
          <n-input-number
            class="l-i-input"
            type="number"
            placeholder="栈限制"
            v-model:value="problem.stackLimit"
          ></n-input-number>
        </n-form-item>
        <n-form-item class="l-item-s" label="难度" path="stackLimit">
          <n-select
            class="l-i-input"
            placeholder="难度"
            v-model:value="problem.difficulty"
            :options="difficultyOptions"
          ></n-select>
        </n-form-item>
      </div>
      <n-form-item label="提示信息" path="hint" class="f-item">
        <v-md-editor
          class="mdEdit"
          :left-toolbar="toolbar"
          v-model="problem.hint"
          height="300px"
          :disabled-menus="[]"
          @upload-image="updateImage"
          :before-preview-change="beforeChange"
        ></v-md-editor>
      </n-form-item>
      <div class="limit">
        <n-form-item class="l-item" label="权限" path="auth">
          <n-select
            class="l-i-input"
            placeholder="权限"
            v-model:value="problem.auth"
            :options="authOptions2"
          ></n-select>
        </n-form-item>
        <n-form-item class="l-item-s" label="类型" path="type">
          <n-select
            class="l-i-input"
            placeholder="类型"
            v-model:value="problem.judgeType"
            :options="typeOptions"
          ></n-select>
        </n-form-item>
        <n-form-item class="l-item-s" label="代码是否可分享" path="codeShare">
          <n-switch
            v-model:value="problem.codeShare"
            :checked-value="1"
            :unchecked-value="0"
          />
        </n-form-item>
        <n-form-item class="l-item" label="标签" path="tagList">
          <n-select
            placeholder="标签"
            multiple
            filterable
            v-model:value="selectedTagList"
            :options="tagList"
            label-field="name"
            value-field="id"
          ></n-select>
        </n-form-item>
      </div>
      <n-form-item label="题面样例" class="f-item-examples">
        <div class="examples">
          <div class="noData" v-show="examples.length == 0">No Data</div>
          <div class="box" v-for="(item, index) in examples" :key="item">
            <div class="b-title">
              样例{{ index + 1 }}
              <n-button
                class="nbtn"
                style="margin-left: auto"
                type="error"
                size="small"
                @click="removeExample(index)"
              >
                <i class="iconfont icon-shanchu"></i>
              </n-button>
            </div>
            <n-collapse-transition class="items" :show="item.isShow">
              <n-form-item class="item" label="输入样例">
                <n-input
                  placeholder="输入样例内容"
                  class="i-i"
                  type="textarea"
                  v-model:value="item.input"
                ></n-input>
              </n-form-item>
              <n-form-item class="item" label="输出样例">
                <n-input
                  placeholder="输出样例内容"
                  class="i-i"
                  type="textarea"
                  v-model:value="item.output"
                ></n-input>
              </n-form-item>
            </n-collapse-transition>
            <div class="b-footer" @click="item.isShow = !item.isShow">
              <i class="iconfont icon-xiangshang" v-show="item.isShow"></i>
              <i class="iconfont icon-xiangxia" v-show="!item.isShow"></i>
            </div>
          </div>
        </div>
      </n-form-item>
      <n-button
        dashed
        size="small"
        class="f-btn"
        type="success"
        @click="appendExample()"
      >
        <i class="iconfont icon-tianjia"></i>添加面板样例
      </n-button>
      <n-form-item label="语言列表" class="f-item">
        <n-checkbox-group v-model:value="selectedLang">
          <n-checkbox
            v-for="item in languages"
            :key="item.language"
            :value="item.language"
            :label="item.language"
          />
        </n-checkbox-group>
      </n-form-item>
      <n-form-item label="代码模板" class="f-item" v-if="ready">
        <n-checkbox-group class="checkbox-group" v-model:value="activeLang">
          <div
            class="checkbox-box"
            v-for="(item, index) in selectedLangWithCode"
            :key="item.language"
          >
            <n-checkbox
              class="checkbox"
              :value="item.language"
              :label="item.language"
            ></n-checkbox>
            <transition>
              <div class="code" v-if="activeLang.includes(item.language)">
                <div class="left">
                  <codeMirrorTree
                    :type="problem.problemType"
                    :data="item"
                    @dataChange="
                      (value) => {
                        selectedLangWithCode[index] = value;
                      }
                    "
                  ></codeMirrorTree>
                </div>
                <div class="right">
                  <n-tooltip trigger="hover">
                    <template #trigger>
                      <n-button
                        size="small"
                        class="r-btn"
                        type="error"
                        dashed
                        @click="resetCodeTemp(index)"
                      >
                        <i class="iconfont icon-zhongzhi"></i>
                      </n-button>
                    </template>
                    重置
                  </n-tooltip>
                </div>
              </div>
            </transition>
          </div>
        </n-checkbox-group>
      </n-form-item>
      <div class="sample-box">
        <n-form-item label="评测数据" path="isUploadCase">
          <div class="sample">
            <n-switch
              class="s-b-switch"
              :rail-style="railStyle"
              v-model:value="problem.isUploadCase"
            >
              <template #unchecked> 手动输入 </template>
              <template #checked> 上传文件 </template>
            </n-switch>
            <div class="isAvg">
              <div class="do">
                <el-tooltip class="box-item" effect="dark" placement="top">
                  <template #content>
                    这只是辅助工具,帮忙分配分数,不对数据有任何的影响
                  </template>
                  <div class="icon">
                    <i class="iconfont icon-wenhao1"></i>
                  </div>
                </el-tooltip>
                <n-switch
                  class="s-b-switch"
                  :rail-style="scoreStyle"
                  v-model:value="isAvg"
                >
                  <template #unchecked> 不平均分 </template>
                  <template #checked> 自动平均 </template>
                </n-switch>
              </div>
              <div class="score" v-show="isAvg">
                总分值:<n-input-number
                  :size="'small'"
                  class="totalScore"
                  placeholder="总分"
                  v-model:value="totalScore"
                ></n-input-number>
              </div>
            </div>
          </div>
        </n-form-item>
        <transition>
          <div v-show="!problem.isUploadCase">
            <n-form-item class="f-item-examples">
              <div class="examples">
                <div
                  class="noData"
                  v-show="problem.problemCaseList.length == 0"
                >
                  No Data
                </div>
                <div
                  class="box"
                  v-for="(item, index) in problem.problemCaseList"
                  :key="item"
                >
                  <div class="b-title">
                    测试用例{{ index + 1 }}
                    <n-switch
                      class="switch"
                      v-model:value="item.status"
                      :checked-value="0"
                      :unchecked-value="1"
                    >
                      <template #checked> 启用中 </template>
                      <template #unchecked> 未启用 </template>
                    </n-switch>
                    <n-button
                      class="nbtn"
                      type="error"
                      size="small"
                      @click="removeSamples(index)"
                    >
                      <i class="iconfont icon-shanchu"></i>
                    </n-button>
                  </div>
                  <n-collapse-transition :show="item.isShow">
                    <div class="items">
                      <n-form-item class="item" label="输入样例">
                        <n-input
                          placeholder="输入样例内容"
                          class="i-i"
                          type="textarea"
                          v-model:value="item.input"
                        ></n-input>
                      </n-form-item>
                      <n-form-item class="item" label="输出样例">
                        <n-input
                          placeholder="输出样例内容"
                          class="i-i"
                          type="textarea"
                          v-model:value="item.output"
                        ></n-input>
                      </n-form-item>
                    </div>
                    <div class="score" v-show="problem.judgeType == 1">
                      <n-form-item class="s-form" label="分值">
                        <n-input-number
                          v-model:value="item.score"
                          class="input"
                          size="small"
                          placeholder=""
                          :min="0"
                          :max="1000"
                        >
                          <template #suffix>
                            <i class="iconfont icon-fenshu"></i>
                          </template>
                        </n-input-number>
                      </n-form-item>
                    </div>
                  </n-collapse-transition>
                  <div
                    class="b-footer"
                    @click="item.isShow = !item.isShow"
                    :style="{ 'border-color': 'rgb(156,90,235)' }"
                  >
                    <i
                      class="iconfont icon-xiangshang"
                      v-show="item.isShow"
                    ></i>
                    <i class="iconfont icon-xiangxia" v-show="!item.isShow"></i>
                  </div>
                </div>
              </div>
            </n-form-item>
            <n-button
              color="rgb(156,90,235)"
              dashed
              size="small"
              class="f-btn"
              @click="appendSamples()"
            >
              <i class="iconfont icon-tianjia"></i>添加测试用例
            </n-button>
          </div>
        </transition>
        <transition>
          <div v-show="problem.isUploadCase" class="upload">
            <el-upload
              accept=".zip"
              drag
              multiple
              :action="`${baseUrl}/judge-backend/manage/problem/upload/case/zip`"
              :show-file-list="false"
              :on-success="finishUpload"
              :headers="{
                Authorization: token,
              }"
            >
              <div style="margin-bottom: 12px">
                <i class="iconfont icon-icon_update bigIcon"></i>
              </div>
              <n-text style="font-size: 16px">
                点击或者拖动文件到该区域来上传
              </n-text>
              <n-p depth="3" style="margin: 8px 0 0 0">
                请不要上传敏感数据
              </n-p>
            </el-upload>
            <div>
              <n-form-item class="f-item-examples">
                <div class="examples">
                  <div
                    class="noData"
                    v-show="problem.problemCaseList2.length == 0"
                  >
                    No Data
                  </div>
                  <div
                    class="box"
                    v-for="(item, index) in problem.problemCaseList2"
                    :key="item"
                  >
                    <div class="b-title">
                      测试用例{{ index + 1 }}
                      <n-switch
                        class="switch"
                        style="margin: auto 2% auto auto"
                        v-model:value="item.status"
                        :checked-value="0"
                        :unchecked-value="1"
                      >
                        <template #checked> 启用中 </template>
                        <template #unchecked> 未启用 </template>
                      </n-switch>
                    </div>
                    <n-collapse-transition :show="item.isShow">
                      <div class="items">
                        <n-form-item class="item" label="输入样例">
                          <n-input
                            disabled
                            placeholder="输入样例内容"
                            class="i-i"
                            type="textarea"
                            v-model:value="item.input"
                          ></n-input>
                        </n-form-item>
                        <n-form-item class="item" label="输出样例">
                          <n-input
                            disabled
                            placeholder="输出样例内容"
                            class="i-i"
                            type="textarea"
                            v-model:value="item.output"
                          ></n-input>
                        </n-form-item>
                      </div>
                      <div class="score" v-show="problem.judgeType == 1">
                        <n-form-item class="s-form" label="分值">
                          <n-input-number
                            v-model:value="item.score"
                            class="input"
                            size="small"
                            placeholder=""
                            :min="0"
                            :max="1000"
                          >
                            <template #suffix>
                              <i class="iconfont icon-fenshu"></i>
                            </template>
                          </n-input-number>
                        </n-form-item>
                      </div>
                    </n-collapse-transition>
                    <div
                      class="b-footer"
                      @click="item.isShow = !item.isShow"
                      :style="{ 'border-color': 'rgb(156,90,235)' }"
                    >
                      <i
                        class="iconfont icon-xiangshang"
                        v-show="item.isShow"
                      ></i>
                      <i
                        class="iconfont icon-xiangxia"
                        v-show="!item.isShow"
                      ></i>
                    </div>
                  </div>
                </div>
              </n-form-item>
            </div>
          </div>
        </transition>
      </div>
      <n-form-item label="来源" path="source" class="f-item">
        <n-input
          placeholder="来源"
          v-model:value="problem.source"
          class="f-i-input"
        ></n-input>
      </n-form-item>
      <div class="limit">
        <n-form-item
          class="l-item-s"
          label="去除代码行末空白符"
          path="codeShare"
        >
          <n-switch v-model:value="problem.isRemoveEndBlank" />
        </n-form-item>
        <n-form-item class="l-item-s" label="公开评测结果" path="codeShare">
          <n-switch v-model:value="problem.openCaseResult" />
        </n-form-item>
      </div>
    </n-form>
    <div class="saveBox">
      <n-button
        class="s-btn"
        type="success"
        size="small"
        @click="handleValidateClick"
        >保存</n-button
      >
    </div>
  </div>
</template>

<script>
import {
  appendProblemAPI,
  getTagListAPI,
  getProblemDetailAPI,
  updateProblemAPI,
  saveCodeTemplateAPI,
  getCodeTemplateAPI,
  uploadProblemImageAPI,
} from "@/api/adminAPI/adminAPI";
import { ElMessage } from "element-plus";
import codeMirrorTree from "@/components/ojComponents/compiler/codeMirrorTree.vue";
import { problemTypeOptions } from "./config/index";
import {
  defineComponent,
  ref,
  reactive,
  onMounted,
  watch,
  computed,
} from "vue";
import { getCurrentInstance } from "vue";
import useStore from "@/store";
import { beforeChange } from "@/utils/global.js";
import { LangeuageConf } from "@/pages/ojPage/quiz/config";
export default defineComponent({
  setup() {
    onMounted(() => {
      getTagList();
      if (route.name === "problemedit") {
        getProblemDetail(route.params.pid);
      } else {
        ready.value = true;
      }
      codeTemplate.pid = route.params.pid;
    });
    const token = localStorage.getItem("TOKEN");
    const that = getCurrentInstance();
    const route = that.appContext.config.globalProperties.$route;
    const router = that.appContext.config.globalProperties.$router;
    const store = useStore();
    const baseUrl = import.meta.env.VITE_APP_URL;
    const problem = reactive({
      problemType: 0,
      problemId: "",
      title: "",
      judgeType: 1,
      timeLimit: 1000,
      memoryLimit: 256,
      stackLimit: 256,
      description: "",
      inputDes: "",
      outputDes: "",
      examples: "",
      source: "原创",
      gid: 0,
      difficulty: 0,
      hint: "",
      auth: 1,
      ioScore: 100,
      codeShare: 1,
      isRemoveEndBlank: true,
      openCaseResult: true,
      isUploadCase: false,
      problemCaseTmpPath: "",
      problemCaseList: [],
      problemCaseList2: [],
      problemLanguageList: [],
      tagList: [],
    });
    let deboundTime = null;
    const totalScore = ref(100);
    const ready = ref(false);
    const isAvg = ref(false);
    const avgScore = () => {
      if (deboundTime) {
        clearTimeout(deboundTime);
      }
      deboundTime = setTimeout(() => {
        if (totalScore.value === null) {
          if (!problem.isUploadCase) {
            problem.problemCaseList.forEach((item) => {
              item.score = parseInt(0);
            });
          } else {
            problem.problemCaseList2.forEach((item) => {
              item.score = parseInt(0);
            });
          }
        } else {
          if (parseInt(totalScore.value) < 0) {
            ElMessage.error("总分不能小于0");
            return;
          }
          if (!problem.isUploadCase) {
            const array = problem.problemCaseList.filter((item) => {
              return !item.status;
            });
            if (array.length === 0) {
              problem.problemCaseList.forEach((item) => {
                item.score = 0;
              });
            } else {
              problem.problemCaseList.forEach((item) => {
                if (!item.status) {
                  item.score = parseInt(
                    parseInt(totalScore.value) / array.length
                  );
                } else {
                  item.score = 0;
                }
              });
            }
          } else {
            const array = problem.problemCaseList2.filter((item) => {
              return !item.status;
            });
            if (array.length === 0) {
              problem.problemCaseList2.forEach((item) => {
                item.score = 0;
              });
            } else {
              problem.problemCaseList2.forEach((item) => {
                if (!item.status) {
                  item.score = parseInt(
                    parseInt(totalScore.value) / array.length
                  );
                } else {
                  item.score = 0;
                }
              });
            }
          }
        }
      }, 300);
    };
    watch(problem, () => {
      if (isAvg.value) {
        avgScore();
      }
    });
    watch(totalScore, () => {
      if (isAvg.value) {
        avgScore();
      }
    });
    watch(isAvg, () => {
      avgScore();
    });
    //测试用例的增删
    const appendSamples = () => {
      problem.problemCaseList.push({
        isShow: true,
        input: "",
        output: "",
        score: 50,
        status: 0,
      });
    };
    const removeSamples = (index) => {
      problem.problemCaseList.splice(index, 1);
    };

    //获取分类列表
    const tagList = ref([]);
    const getTagList = async () => {
      tagList.value.length = 0;
      await getTagListAPI()
        .then((res) => {
          if (res.data.code === 200) {
            res.data.data.forEach((ele) => {
              ele.tagList.forEach((item) => {
                tagList.value.push(item);
              });
            });
          }
        })
        .catch((err) => {
          console.log(err);
        });
    };

    //题面样例的增删
    const examples = ref([
      {
        isShow: true,
        input: "",
        output: "",
      },
    ]);
    const appendExample = () => {
      if (examples.value.length <= 10) {
        examples.value.push({
          isShow: true,
          input: "",
          output: "",
        });
      } else {
        ElMessage.error("超过限制样例数");
      }
    };
    const removeExample = (index) => {
      examples.value.splice(index, 1);
    };

    //表单校验规则
    const rules = {
      problemId: {
        required: true,
        message: "请输入展示ID",
        trigger: ["input", "blur"],
      },
      title: {
        required: true,
        message: "请输入标题",
        trigger: ["input", "blur"],
      },
      timeLimit: {
        type: "number",
        required: true,
        message: "请输入时间限制",
        trigger: ["input", "blur"],
      },
      memoryLimit: {
        type: "number",
        required: true,
        message: "请输入内存限制",
        trigger: ["input", "blur"],
      },
      stackLimit: {
        type: "number",
        required: true,
        message: "请输入栈限制",
        trigger: ["input", "blur"],
      },
      problemType: {
        type: "number",
        required: true,
        message: "请选择类型",
        trigger: ["blur", "change"],
      },
    };

    //添加题目
    const appendProblem = async () => {
      formatData();
      await appendProblemAPI(problem)
        .then((res) => {
          if (res.data.code === 200) {
            codeTemplate.pid = res.data.data;
            saveCodeTemplate();
          }
        })
        .catch((err) => {
          console.log("系统错误");
        });
    };

    //表单校验
    const formRef = ref(null);
    const handleValidateClick = (e) => {
      e.preventDefault();
      if (problem.isUploadCase) {
        problem.problemCaseList = problem.problemCaseList2;
      }
      if (problem.description.length == 0) {
        ElMessage.error("请输入：问题描述");
        return;
      }
      if (problem.inputDes.length == 0) {
        ElMessage.error("请输入：输入描述");
        return;
      }
      if (problem.outputDes.length == 0) {
        ElMessage.error("请输入：输出描述");
        return;
      }
      if (problem.problemCaseList.length == 0) {
        ElMessage.error("至少输入一个测试用例");
        return;
      }
      if (examples.value.length == 0) {
        ElMessage.error("至少输入一个题面样例");
        return;
      }
      if (selectedLang.value.length == 0) {
        ElMessage.error("请选择编程语言");
        return;
      }

      formRef.value.validate((errors) => {
        if (!errors) {
          if (route.name === "problemedit") {
            updateProblem();
            return;
          }
          appendProblem();
        }
      });
    };
    //获取题目详情
    const getProblemDetail = async (id) => {
      await getProblemDetailAPI(id)
        .then((res) => {
          if (res.data.code === 200) {
            getCodeTemplate(res.data.data.id);
            const temp = [];
            if (res.data.data.tagList) {
              res.data.data.tagList.forEach((ele) => {
                temp.push(ele.id);
              });
            }
            selectedTagList.value = temp;

            const temp2 = [];
            res.data.data.problemLanguageList.forEach((ele) => {
              temp2.push(ele.language);
            });
            selectedLang.value = temp2;

            try {
              res.data.data.examples = JSON.parse(res.data.data.examples);
              const temp3 = [];
              for (
                let index = 0;
                index < res.data.data.examples.input.length;
                index++
              ) {
                temp3.push({
                  input: res.data.data.examples.input[index],
                  output: res.data.data.examples.output[index],
                  isShow: true,
                });
              }
              examples.value = temp3;
            } catch (error) {
              res.data.data.examples = "";
            }

            Object.assign(problem, res.data.data);

            if (res.data.data.isUploadCase) {
              problem.problemCaseList2 = res.data.data.problemCaseList.map(
                (ele) => {
                  return {
                    input: ele.input,
                    output: ele.output,
                    score: ele.score || 0,
                    status: ele.status,
                    isShow: true,
                  };
                }
              );
              problem.problemCaseList = [];
            }
          }
        })
        .catch((err) => {
          console.log("系统错误");
        });
    };
    //更新题目
    const updateProblem = async () => {
      formatData();
      await updateProblemAPI(problem)
        .then((res) => {
          if (res.data.code === 200) {
            saveCodeTemplate();
          }
        })
        .catch((err) => {
          console.log("系统错误");
        });
    };
    const formatData = () => {
      const ex = {
        input: [],
        output: [],
      };
      examples.value.forEach((ele) => {
        ex.input.push(ele.input);
        ex.output.push(ele.output);
      });
      problem.examples = JSON.stringify(ex);

      const langArr = [];
      selectedLang.value.forEach((ele) => {
        langArr.push({ language: ele });
      });
      problem.problemLanguageList = langArr;

      const tagArr = [];
      selectedTagList.value.forEach((ele) => {
        tagArr.push({ id: ele });
      });

      if (problem.judgeType == 0) {
        problem.problemCaseList.forEach((ele) => {
          delete ele.score;
        });
      }

      problem.tagList = tagArr;
    };

    //代码模板
    const selectedLang = ref([
      "Java",
      "C",
      "C++",
      "C With O2",
      "C++ With O2",
      "Python2",
      "Python3",
      "PyPy2",
      "PyPy3",
    ]);
    const selectedLangWithCode = ref([]);
    watch(
      () => selectedLang.value,
      () => {
        selectedLangWithCode.value =
          selectedLang.value.map((item) => {
            return { language: item, code: "", format: "[]" };
          }) || [];
      },
      { immediate: true, deep: true }
    );
    const selectedTagList = ref([]);
    const activeLang = ref([]);

    const codeTemplate = reactive({
      pid: "",
      problemCodeTemplateList: [
        {
          language: "Java",
          code: '[{"fileName":"Main.java","content":"//PREPEND BEGIN\\nimport java.util.Scanner;\\n//PREPEND END\\n\\npublic class Main{\\n//TEMPLATE BEGIN\\n    public static Integer add(int a,int b){\\n        return _______;\\n    }\\n//TEMPLATE END\\n\\n//APPEND BEGIN\\npublic static void main(String[] args){\\n    System.out.println(add(a,b));\\n}\\n//APPEND END\\n}"}]',
          format: "[]",
        },
        {
          language: "C",
          code: '//PREPEND BEGIN\n#include <stdio.h>\n//PREPEND END\n//TEMPLATE BEGIN\nint add(int a, int b) {\n// Please fill this blank\n    return ___________;\n}\n//TEMPLATE END\n//APPEND BEGIN\nint main() {\n    printf("%d", add(1, 2));\n    return 0;\n}\n//APPEND END',
        },
        {
          language: "C++",
          code: "//PREPEND BEGIN\n#include <stdio.h>\n//PREPEND END\n//TEMPLATE BEGIN\nint add(int a, int b) {\n// Please fill this blank\n    return ___________;\n}\n//TEMPLATE END\n//APPEND BEGIN\nint main() {\n    cout << add(1, 2);\n    return 0;\n}\n//APPEND END",
        },
        {
          language: "C With O2",
          code: '//PREPEND BEGIN\n#include <stdio.h>\n//PREPEND END\n//TEMPLATE BEGIN\nint add(int a, int b) {\n// Please fill this blank\n    return ___________;\n}\n//TEMPLATE END\n//APPEND BEGIN\nint main() {\n    printf("%d", add(1, 2));\n    return 0;\n}\n//APPEND END',
        },
        {
          language: "C++ With O2",
          code: "//PREPEND BEGIN\n#include <stdio.h>\n//PREPEND END\n//TEMPLATE BEGIN\nint add(int a, int b) {\n// Please fill this blank\n    return ___________;\n}\n//TEMPLATE END\n//APPEND BEGIN\nint main() {\n    cout << add(1, 2);\n    return 0;\n}\n//APPEND END",
        },
        {
          language: "Python2",
          code: "",
        },
        {
          language: "Python3",
          code: "",
        },
        {
          language: "PyPy2",
          code: "",
        },
        {
          language: "PyPy3",
          code: "",
        },
      ],
      languageList: [
        "Java",
        "C",
        "C++",
        "C With O2",
        "C++ With O2",
        "Python2",
        "Python3",
        "PyPy2",
        "PyPy3",
      ],
    });

    //重置代码模板
    // const resetCodeTemp = (index) => {

    // }
    //保存代码模板
    const saveCodeTemplate = async () => {
      let res = selectedLangWithCode.value.filter((item) => {
        return activeLang.value.includes(item.language);
      });
      for (let i = 0; i < res.length; i++) {
        let flag = false;
        for (let j = 0; j < res[i].format.length; j++) {
          if (res[i].format[j].label == LangeuageConf[res[i].language]) {
            flag = true;
          }
        }
        if (!flag) {
          ElMessage.error("请填写正确的代码模板");
          return;
        }
      }

      let resu = res.map((item) => {
        const codeRes = [];
        const findleave = (tree, stack) => {
          for (const node of tree) {
            if (node.type == "file") {
              codeRes.push({
                fileName: stack.length
                  ? stack.join("/") + "/" + node.label
                  : node.label,
                content: node.code,
              });
              stack.pop();
            } else {
              stack.push(node.label);
              findleave(node.children, stack);
            }
          }
        };
        findleave(item.format, []);
        return {
          language: item.language,
          code: JSON.stringify(codeRes),
          format: JSON.stringify(item.format),
        };
      });

      await saveCodeTemplateAPI({
        pid: codeTemplate.pid,
        problemCodeTemplateList: resu,
      })
        .then((res) => {
          if (res.data.code === 200) {
            ElMessage.success(res.data.msg);
            router.push({
              path: "/admin/problem/list",
            });
          }
        })
        .catch((err) => {
          console.log(err);
        });
    };
    //请求代码模板
    const getCodeTemplate = async (pid) => {
      await getCodeTemplateAPI(pid)
        .then((res) => {
          if (res.data.code === 200) {
            activeLang.value = [];
            codeTemplate.languageList = selectedLang.value;
            codeTemplate.problemCodeTemplateList.forEach((ele) => {
              res.data.data.forEach((item) => {
                if (ele.language == item.language) {
                  ele.code = item.code;
                }
                if (!activeLang.value.includes(item.language)) {
                  activeLang.value.push(item.language);
                }
              });
            });
            let temps = selectedLangWithCode.value;
            for (let i = 0; i < temps.length; i++) {
              for (let j = 0; j < res.data.data.length; j++) {
                if (temps[i].language == res.data.data[j].language) {
                  temps[i].code = res.data.data[j].code;
                  temps[i].format = JSON.parse(res.data.data[j].format);
                }
              }
            }
            ready.value = true;
          }
        })
        .catch((err) => {
          console.log(err);
        });
    };

    const finishUpload = (res) => {
      if (res.code === 200) {
        problem.problemCaseTmpPath = res.data.fileListDir;
        problem.problemCaseList2.length = 0;
        res.data.fileList.forEach((ele) => {
          problem.problemCaseList2.push({
            isShow: true,
            score: 50,
            input: ele.input,
            output: ele.output,
            status: 0,
          });
        });
      }
    };
    const updateImage = async (event, insertImage, files) => {
      if (
        files[0].name.includes("png") ||
        files[0].name.includes("jpg") ||
        files[0].name.includes("gif")
      ) {
        let data = new FormData();
        data.append("file", files[0]);
        await uploadProblemImageAPI(data).then((res) => {
          if (res.data.code === 200) {
            insertImage({
              url: res.data.data,
              desc: files[0].name,
              width: "10%",
              height: "10%",
            });
          }
        });
      } else {
        ElMessage.error("请上传jpg、png、gif类型的图片");
      }
    };
    const languages = ref([
      {
        language: "Java",
      },
      {
        language: "C",
      },
      {
        language: "C++",
      },
      {
        language: "C With O2",
      },
      {
        language: "C++ With O2",
      },
      {
        language: "Python2",
      },
      {
        language: "Python3",
      },
      {
        language: "PyPy2",
      },
      {
        language: "PyPy3",
      },
    ]);
    return {
      finishUpload,
      baseUrl,
      token,
      problem,
      store,
      status: {
        titleStatus: "",
      },
      rules,
      difficultyOptions: [
        {
          label: "简单",
          value: 0,
        },
        {
          label: "中等",
          value: 1,
        },
        {
          label: "困难",
          value: 2,
        },
      ],
      typeOptions: [
        {
          label: "ACM",
          value: 0,
        },
        {
          label: "OI",
          value: 1,
        },
      ],
      authOptions2: [
        {
          label: "公开题目",
          value: 1,
        },
        {
          label: "私有题目",
          value: 2,
        },
        {
          label: "比赛题目",
          value: 3,
        },
      ],
      tagList,
      languages: languages,
      examples,
      railStyle: ({ focused, checked }) => {
        const style = {};
        if (checked) {
          style.background = "rgba(134,46,228,0.8)";
          if (focused) {
            style.boxShadow = "0 0 0 2px #d220f040";
          }
        } else {
          style.background = "rgba(60,128,242,0.8)";
          if (focused) {
            style.boxShadow = "0 0 0 2px #2080f040";
          }
        }
        return style;
      },
      scoreStyle: ({ focused, checked }) => {
        const style = {};
        if (checked) {
          style.background = "#18a058";
          if (focused) {
            style.boxShadow = "0 0 0 2px #18a058";
          }
        } else {
          style.background = "rgb(197 33 33 / 80%)";
          if (focused) {
            style.boxShadow = "0 0 0 2px rgb(197 33 33 / 80%)";
          }
        }
        return style;
      },
      toolbar:
        "undo redo clear | h bold italic strikethrough quote | ul ol table hr | link tip code  | emoji image",
      formRef,
      route,
      ready,
      selectedLang,
      selectedLangWithCode,
      selectedTagList,
      appendExample,
      removeExample,
      appendSamples,
      removeSamples,
      handleValidateClick,
      getProblemDetail,
      saveCodeTemplate,
      activeLang,
      codeTemplate,
      // resetCodeTemp,
      updateImage,
      isAvg,
      totalScore,
      problemTypeOptions,
      beforeChange,
    };
  },
});
</script>

<style lang="less" scoped>
.problemCreate {
  margin: auto;
  width: 96%;
  padding: 15px 10px;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 12px 12px 50px #d9d9d9, -12px -12px 50px #ffffff;

  .p-header {
    display: flex;
    padding-bottom: 10px;
    border-bottom: 2px solid @lineColor;

    .p-h-title {
      height: 30px;
      line-height: 30px;
      font-size: 20px;
      font-weight: 600;
      color: #555;
      display: flex;
      text-align: center;

      .iconfont {
        margin: auto 0;
        font-weight: 700;
        font-size: 28px;
        height: 30px;
      }
    }
  }

  .form {
    margin-top: 20px;
    width: 100%;

    .f-item {
      .f-i-input {
        width: 90%;
      }

      .checkbox-group {
        width: 100%;

        .checkbox-box {
          width: 100%;

          .checkbox {
            margin: 5px 0;
          }

          .code {
            width: 99%;
            height: 300px;
            margin: 5px 0 10px 10px;
            display: flex;

            .left {
              width: 64%;
            }

            .right {
              width: 36%;
              display: flex;
              flex-direction: column;

              .r-btn {
                width: 10%;
                margin: 0 5px 5px 5px;
              }
            }
          }
        }
      }
    }

    .codeTemplate {
      margin-top: 10px;

      .noData {
        width: 100%;
        color: #888;
        text-align: center;
      }

      .n-btn {
        margin: auto 10px auto 0;
      }
    }

    .f-item-examples {
      width: 100%;

      .examples {
        width: 100%;
        display: flex;
        flex-wrap: wrap;

        .noData {
          width: 100%;
          color: #888;
          text-align: center;
        }

        .box {
          width: 100%;
          margin: 10px auto;
          border: 1px solid rgb(213, 213, 214);
          border-radius: 10px;
          overflow: hidden;

          .b-title {
            width: 100%;
            font-weight: 600;
            font-size: 16px;
            padding: 5px;
            display: flex;
            padding-left: 15px;

            .b-t-span {
              margin-left: 30px;
            }

            .n-input {
              width: 150px;
              display: flex;
              margin: auto 0 auto 2%;
              color: rgb(129, 123, 123);

              .input {
                width: 150px;
                margin: auto;
              }
            }

            .nbtn {
              margin: auto 2%;
            }

            .switch {
              margin: auto 0 auto auto;
              font-size: 12px;
            }
          }

          .b-footer {
            width: 100%;
            height: 30px;
            line-height: 30px;
            display: flex;
            justify-content: center;
            border-top: 1px dashed rgb(58, 159, 85);

            .iconfont {
              height: 30px;
            }

            &:hover {
              background-color: rgb(235, 238, 245);
            }
          }

          .items {
            display: flex;
            width: 100%;
            margin: 0 auto;
            padding: 10px 0;
            background-color: rgb(249, 250, 252);

            .item {
              width: 45%;
              margin: 0 auto;
            }
          }

          .score {
            width: 100%;
            margin: auto;
            background-color: rgb(249, 250, 252);
            display: flex;

            .s-form {
              width: 95%;
              margin: 0 auto 20px auto;

              .input {
                width: 100%;
              }
            }
          }
        }
      }

      .f-i-input {
        width: 90%;
      }
    }

    .f-btn {
      width: 100%;
      margin-bottom: 10px;
    }
  }

  .saveBox {
    width: 100%;
    display: flex;
    justify-content: center;

    .s-btn {
      width: 10%;
    }
  }

  .limit {
    display: flex;
    width: 100%;

    .l-item {
      margin: auto 25px auto 0;
      width: 25%;
    }

    .l-item-s {
      min-width: 10%;
      margin-right: 20px;
    }
  }

  .sample-box {
    width: 100%;

    .upload {
      .bigIcon {
        font-size: 30px;
      }
    }

    .sample {
      display: flex;
      align-items: center;
      width: 100%;

      .isAvg {
        display: flex;
        align-items: center;
        margin-left: 5%;
        font-weight: 500;
        color: rgba(85, 85, 85, 0.921);

        .title {
          font-size: 1rem;
          margin-right: 5px;
          color: #222222c4;
        }

        .score {
          display: flex;
          align-items: center;
          font-size: 1rem;
          margin-left: 10px;

          ::v-deep(.totalScore) {
            margin-left: 10px;
            width: 100px;
          }
        }

        .do {
          display: flex;
          align-items: center;
        }

        .icon {
          width: 20px;
          height: 20px;
          display: flex;
          justify-content: center;
          align-items: center;
          border-radius: 50%;
          background-color: #292626c3;
          color: #fff;
          margin-right: 5px;
        }
      }
    }
  }
}

.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}

.drawer {
  .drawer-box {
    display: flex;
    position: static;

    .left {
      width: 100%;
    }

    .right {
      position: absolute;
      right: 4%;
      display: flex;
      flex-direction: column;
    }

    .btn {
      margin: 5px 0 0 0;
    }
  }
}

.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}
</style>
